package net.expectx.pay.gateway.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import net.expectx.common.single.base.BaseResult;
import net.expectx.pay.core.util.AliPayUtil;
import net.expectx.pay.gateway.common.AdminResult;
import net.expectx.pay.gateway.common.util.RedisUtil;
import net.expectx.pay.gateway.dao.bean.ProductOrderHeader;
import net.expectx.pay.gateway.dao.bean.ProductOrderHeaderExample;
import net.expectx.pay.gateway.dao.bean.ProductOrderPaymentRecord;
import net.expectx.pay.gateway.rpc.api.ProductOrderHeaderService;
import net.expectx.pay.gateway.rpc.api.ProductOrderPaymentRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 异步通知
 */
@Controller
@RequestMapping("/pay/")
public class PayNotifyUrlController {
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private ProductOrderHeaderService productOrderHeaderService;
    @Autowired
    private ProductOrderPaymentRecordService productOrderPaymentRecordService;
    @ApiOperation(value = "微信支付通知界面")
    @RequestMapping(value = "/weiXinPayNotify", method = RequestMethod.POST)
    public void weiXinPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setContentType("text/xml");
        String inputLine = null;
        StringBuffer receiveData = new StringBuffer();
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
            while ((inputLine = in.readLine()) != null) {
                receiveData.append(inputLine);
            }
            final Map<String, String> map = WXPayUtil.xmlToMap(receiveData.toString());
            System.out.println("支付通知:"+ JSONObject.toJSONString(map));
            threadPoolTaskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        String appId = map.get("sub_appid");
                        String outTradeNo = map.get("out_trade_no");
                        String tradeNo = map.get("transaction_id");
                        String totalAmount = new BigDecimal(map.get("total_fee")).divide(new BigDecimal(100)).doubleValue()+"";
                        String gmtPayment = map.get("time_end");
                        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");
                        System.out.println(simpleDateFormat.parse(gmtPayment));
                        gmtPayment = simpleDateFormat.parse(gmtPayment).getTime() + "";
                        /**
                         * 发送异步消息通知
                         */
                        ProductOrderHeaderExample orderHeaderExample = new ProductOrderHeaderExample();
                        orderHeaderExample.createCriteria().andOrderIdEqualTo(outTradeNo);
                        List<ProductOrderHeader> orderHeaders = productOrderHeaderService.selectByExample(orderHeaderExample);
                        if (!orderHeaders.isEmpty()) {
                            ProductOrderHeader productOrderHeader = orderHeaders.get(0);
                            ProductOrderPaymentRecord orderPaymentRecord = productOrderHeader.getProductOrderPaymentRecord();

                            productOrderHeader.setOrderStatus("1");
                            productOrderHeader.setGmtModified(System.currentTimeMillis());

                            orderPaymentRecord.setTradeNo(tradeNo);
                            orderPaymentRecord.setTotalFee(new BigDecimal(totalAmount));
                            orderPaymentRecord.setPayStatus("1");
                            orderPaymentRecord.setFinishTime(Long.valueOf(gmtPayment));
                            orderPaymentRecord.setSubject(productOrderHeader.getOrderName());
                            orderPaymentRecord.setDesc(productOrderHeader.getOrderDesc());
                            orderPaymentRecord.setAccount(appId);
                            orderPaymentRecord.setChannelPayway(productOrderHeader.getChannelId()+"");
                            orderPaymentRecord.setChannelPaywayName(map.get("trade_type"));
                            BaseResult baseResult = productOrderPaymentRecordService.doPayResult(productOrderHeader, orderPaymentRecord);
                            System.out.println(baseResult);
                            if (baseResult.isSuccess()){
                                if (!orderHeaders.isEmpty()){
                                    ProductOrderHeader orderHeader=(ProductOrderHeader) baseResult.getData();
                                    Jedis jedis= net.expectx.pay.gateway.common.util.RedisUtil.getJedis();
                                    jedis.hset("EXPAY:productOrder",orderHeader.getOrderId(), JSONObject.toJSONString(orderHeader));
                                }

                            }

                           /* Map map = Maps.newHashMapWithExpectedSize(7);
                            map.put("channel", "NotifyUrl");
                            map.put("orderId", outTradeNo);

                            map.put("notifyUrl", productOrderHeader.getNotifyUrl());
                            map.put("params", "success=true&msg=支付成功&amount=" + totalAmount + "&merchant_order_no=" + productOrderHeader.getMerchantOrderId() + "&trade_no=" + outTradeNo + "&payment_time=" + gmtPayment + "&pay_channel=" + orderPaymentRecord.getChannelPayway() + "&pay_channel_name=" + orderPaymentRecord.getChannelPaywayName());
                            RedisUtil.publishMsg("PublishMsg", JSON.toJSONString(map));*/
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }




                }
            });


            StringBuffer xml = new StringBuffer();
            Map xmlMap= Maps.newHashMapWithExpectedSize(7);
            xmlMap.put("return_code","SUCCESS");
            xmlMap.put("return_msg","OK");

            xml.append("<xml>");
            xml.append("\r\n");
            xml.append("<return_code>");
            xml.append("SUCCESS");
            xml.append("</return_code>");
            xml.append("\r\n");
            xml.append("<return_msg>");
            xml.append("OK");
            xml.append("</return_msg>");
            xml.append("\r\n");
            xml.append("</xml>");
            response.getWriter().write(WXPayUtil.mapToXml(xmlMap));
        } catch (IOException e) {
        } finally {
            try {
                if (null != in) {
                    in.close();
                }
            } catch (IOException e) {

            }
        }
    }


    @ApiOperation(value = "支付宝支付通知界面")
    @RequestMapping(value = "/aLiPayNotifyUrl", method = RequestMethod.POST)
    public void aLiPayNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer;
        Map<String, String> params = Maps.newHashMapWithExpectedSize(7);
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        System.out.println("支付通知界面:" + JSON.toJSONString(params));


        boolean signVerified = AliPayUtil.rsaCheckV1(params);
        System.out.println("验证签名结果:" + signVerified);
        String appId = params.get("app_id");
        String desc = params.get("body");
        String subject = params.get("subject");
        String totalAmount = params.get("total_amount");
        String gmtPayment = params.get("gmt_payment");
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        gmtPayment =sdf.parse(gmtPayment).getTime()+"";
        String outTradeNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        /**
         * 发送异步消息通知
         */
        ProductOrderHeaderExample orderHeaderExample = new ProductOrderHeaderExample();
        orderHeaderExample.createCriteria().andOrderIdEqualTo(outTradeNo);
        List<ProductOrderHeader> orderHeaders = productOrderHeaderService.selectByExample(orderHeaderExample);
        if (!orderHeaders.isEmpty()) {
            ProductOrderHeader productOrderHeader = orderHeaders.get(0);
            ProductOrderPaymentRecord orderPaymentRecord = productOrderHeader.getProductOrderPaymentRecord();

            productOrderHeader.setOrderStatus("1");
            productOrderHeader.setGmtModified(System.currentTimeMillis());

            orderPaymentRecord.setTradeNo(tradeNo);
            orderPaymentRecord.setTotalFee(new BigDecimal(totalAmount));
            orderPaymentRecord.setPayStatus("1");
            orderPaymentRecord.setFinishTime(Long.valueOf(gmtPayment));
            orderPaymentRecord.setSubject(subject);
            orderPaymentRecord.setDesc(desc);
            orderPaymentRecord.setAccount(appId);
            orderPaymentRecord.setChannelPayway(productOrderHeader.getChannelId()+"");
            BaseResult baseResult = productOrderPaymentRecordService.doPayResult(productOrderHeader, orderPaymentRecord);
            if (baseResult.isSuccess()){
                orderHeaders = productOrderHeaderService.selectByExample(orderHeaderExample);
                if (!orderHeaders.isEmpty()){
                    ProductOrderHeader orderHeader=orderHeaders.get(0);
                    Jedis jedis= net.expectx.pay.gateway.common.util.RedisUtil.getJedis();
                    jedis.hset("EXPAY:productOrder",orderHeader.getOrderId(), JSONObject.toJSONString(orderHeader));
                }

            }
            System.out.println(baseResult);

/*
            Map map = Maps.newHashMapWithExpectedSize(7);
            map.put("channel", "NotifyUrl");
            map.put("orderId", outTradeNo);

            map.put("notifyUrl", productOrderHeader.getNotifyUrl());
            map.put("params", "success=true&msg=支付成功&amount="+totalAmount+"&merchant_order_no="+productOrderHeader.getMerchantOrderId()+"&trade_no="+outTradeNo+"&payment_time="+gmtPayment+"&pay_channel="+orderPaymentRecord.getChannelPayway()+"&pay_channel_name="+orderPaymentRecord.getChannelPaywayName());
            RedisUtil.publishMsg("PublishMsg", JSON.toJSONString(map));*/
        }


        if (signVerified) {

        }


        writer = response.getWriter();
        writer.println("success");
        writer.flush();
        writer.close();
    }

    @RequestMapping(value = "{orderId}/orderStatus")
    @ResponseBody
    public Object orderStatus(@PathVariable(value = "orderId") String orderId) {
        Jedis jedis= RedisUtil.getJedis();
        String result=jedis.hget("EXPAY:productOrder",orderId);
        jedis.close();
        if (null==result){
            return new AdminResult(false, 0, "参数被篡改了", null);
        }
        return new AdminResult(true, 200, null, JSONObject.parseObject(result).getString("orderStatus"));
    }
    @ApiOperation(value = "支付返回界面")
    @RequestMapping(value = "/aLiPayReturnUrl", method = RequestMethod.GET)
    public String aLiPayReturnUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, String> params = Maps.newHashMapWithExpectedSize(7);
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iterator = requestParams.keySet().iterator(); iterator.hasNext(); ) {
            String name = iterator.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        String outTradeNo = params.get("out_trade_no");
        ProductOrderHeaderExample productOrderHeaderExample=new ProductOrderHeaderExample();
        productOrderHeaderExample.createCriteria().andOrderIdEqualTo(outTradeNo);
        List<ProductOrderHeader>productOrderHeaders=productOrderHeaderService.selectByExample(productOrderHeaderExample);
        if (!productOrderHeaders.isEmpty()){
            request.setAttribute("orderHeader",productOrderHeaders.get(0));
        }

        return "pay_success";
    }


}
